﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Abp.AspNetCore.Mvc.Authorization;
using Abp.AspNetCore.Mvc.Extensions;
using Abp.UI;
using FwProject.Authorization.Users;
using FwProject.Controllers;
using FwProject.Core.Restaurant;
using FwProject.Core.SettlementInfoModel;
using FwProject.Distribution;
using FwProject.Distribution.Dto;
using FwProject.ManagerConfig;
using FwProject.PrePaymentInfo;
using FwProject.PrePaymentInfo.Dto;
using FwProject.Settlement;
using FwProject.Settlement.Dto;
using FwProject.Users;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;

namespace FwProject.Web.Controllers
{
    [AbpMvcAuthorize]
    public class SettlementController : FwProjectControllerBase
    {
        private readonly ISettlementInfoAppService _settlementInfoAppService;
        private readonly IUserAppService _userAppService;
        private readonly IDistributionAppService _distributionAppService;
        private readonly IHostingEnvironment _env;
        private readonly IPrePaymentInfoAppService _prePaymentInfoAppService;

        private readonly ISettlementAccountAppService _settlementAccountAppService;
        private readonly IConfigInfoAppService _configInfoAppService;

        private readonly IDistributionLineAppService _distributionLineAppService;
        public SettlementController(ISettlementInfoAppService settlementInfoAppService, IUserAppService userAppService, IDistributionAppService distributionAppService, IHostingEnvironment env, IPrePaymentInfoAppService prePaymentInfoAppService, ISettlementAccountAppService settlementAccountAppService, IConfigInfoAppService configInfoAppService, IDistributionLineAppService distributionLineAppService)
        {
            _userAppService = userAppService;
            _settlementInfoAppService = settlementInfoAppService;
            _distributionAppService = distributionAppService;
            _env = env;
            _prePaymentInfoAppService = prePaymentInfoAppService;
            _settlementAccountAppService = settlementAccountAppService;
            _configInfoAppService = configInfoAppService;
            _distributionLineAppService = distributionLineAppService;
        }

        public async Task<IActionResult> Index(int pageIdx, int size, DateTime? beginTime, DateTime? endTime, DateTime? beginDate, DateTime? endDate, string RestaurantName, long? DriverName, Core.SettlementInfoModel.ExamineStatus? ExamineStatus, RestaurantPayStatus? RestaurantPayStatus, Guid? Line)
        {
            if (pageIdx == 0)
                pageIdx = 1;

            if (size == 0)
                size = 20;


            var users = await _userAppService.GetAllAgentPeoperAsync();


            ViewBag.Cashier = users.Select(o => new SelectListItem() { Value = o.Id.ToString(), Text = o.Name });

            var lines = await _distributionLineAppService.GetAllLineAsync();
            ViewBag.Line = lines.Select(o => new SelectListItem() { Value = o.Id.ToString(), Text = o.LineName });

            if (Request.IsAjaxRequest())
            {
                var model = await _settlementInfoAppService.GetReceivablePagedListAsync(pageIdx, size, beginTime, endTime,beginDate,endDate, RestaurantName, DriverName, ExamineStatus, RestaurantPayStatus, Line);
                return PartialView("IndexPartial", model);
            }

            return View();
        }

        public async Task<IActionResult> BatchReview(string Ids)
        {
            await _settlementInfoAppService.BatchReview(Ids);
            return Json("0");
        }

        public async Task<JsonResult> GetDistributionInfo(Guid id)
        {
            var model = await _distributionAppService.GetDistributionInfoAsync(id);
            return Json(model);
        }

        public async Task<IActionResult> Examine(Guid id)
        {
            var model1 = await _settlementInfoAppService.GetBySettlementIdAsync(id);

            var model2 = await _distributionAppService.GetDistributionInfoAsync(id);
            Tuple<SettlementReceivableDto, List<DistributionDto>> tuple = new Tuple<SettlementReceivableDto, List<DistributionDto>>(model1, model2);

            return View(tuple);
        }

        public async Task<ActionResult> EditStatus(Guid id)
        {
            await _settlementInfoAppService.UpdateStatus(id);

            return Redirect("/Settlement/Examine?id=" + id);
        }

        public async Task<IActionResult> EditDiscountprice(Guid id, decimal Discountprice)
        {
            await _settlementInfoAppService.UpdateDiscountprice(id, Discountprice);
            return Json(id);
        }

        public async Task<ActionResult> ExaminePrint(Guid id)
        {
            var model1 = await _settlementInfoAppService.GetBySettlementIdAsync(id);

            var model2 = await _distributionAppService.GetDistributionInfoAsync(id);
            Tuple<SettlementReceivableDto, List<DistributionDto>> tuple = new Tuple<SettlementReceivableDto, List<DistributionDto>>(model1, model2);
            return View(tuple);
        }

        public async Task<IActionResult> ExportExcel(string RestaurantName, DateTime? beginTime, DateTime? endTime, long? DriverName, Core.SettlementInfoModel.ExamineStatus? ExamineStatus, RestaurantPayStatus? RestaurantPayStatus, Guid? Line)
        {
            var list = await _settlementInfoAppService.GetExportReceivableListAsync(beginTime, endTime, RestaurantName, DriverName, ExamineStatus, RestaurantPayStatus, Line);
            return DoExcel<SettlementReceivableDto>(list, _env);
        }

        public async Task<JsonResult> DeleteSettlement(Guid[] che)
        {
            await _settlementInfoAppService.DeleteSettlement(che);
            return Json(1);
        }


        #region 预收款

        public async Task<IActionResult> AdvancePayment(int? pageIdx, int size, PrePaymentInfoStatus? PrePaymentInfoStatus, string keyword = "")
        {
            var pa = pageIdx ?? 1;

            if (size == 0)
                size = 20;

            var s = await _prePaymentInfoAppService.GetPagedListAsync(pa, size, PrePaymentInfoType.收预交金, keyword, PrePaymentInfoStatus);
            if (Request.IsAjaxRequest())
                return PartialView("AdvancePaymentPartial", s);

            return View(s);
        }
        /// <summary>
        /// 导出预收款列表
        /// </summary>
        /// <param name="keyword"></param>
        /// <returns></returns>
        public async Task<IActionResult> ExportAdvancePayment(string keyword = "")
        {
            var list = await _prePaymentInfoAppService.GetAllListAsync(PrePaymentInfoType.收预交金, keyword);
            return DoExcel<PrePaymentInfoOutputDto>(list, _env);
        }


        public async Task<IActionResult> AdvancePaymentPrint(Guid id)
        {
            var entity = await _prePaymentInfoAppService.GetEntityAsync(id);
            return View(entity);
        }



        public async Task<IActionResult> CreateAdvancePayment()
        {
            var list = await _settlementAccountAppService.GetAllSettlementAccountAsync();
            ViewBag.Account = list.Select(o => new SelectListItem() { Value = o.Id.ToString(), Text = o.Name });
            return View(new PrePaymentInfoEnterDto() { PrePaymentInfoType = PrePaymentInfoType.收预交金 });
        }
        [HttpPost]
        public async Task<IActionResult> CreateAdvancePayment(PrePaymentInfoEnterDto input)
        {
            var id = await _prePaymentInfoAppService.CreateAsync(input);
            return Json(id);
        }



        public async Task<IActionResult> EditAdvancePayment(Guid id)
        {
            var entity = await _prePaymentInfoAppService.GetEnterDto(id);
            var returnPrepayment = await _prePaymentInfoAppService.GetListByRestaurantIdAsync(entity.RestaurantInfoId);
            ViewBag.ReturnPrepayment = returnPrepayment.Sum(o=>o.PrePaymentPrice);

            var list = await _settlementAccountAppService.GetAllSettlementAccountAsync();
            ViewBag.Account = list.Select(o => new SelectListItem() { Value = o.Id.ToString(), Text = o.Name });
            ViewBag.Id = id;
            return View(entity);
        }

        [HttpPost]
        public async Task<IActionResult> EditAdvancePayment(Guid id, PrePaymentInfoEnterDto input)
        {
            await _prePaymentInfoAppService.ModifyAsync(id, input);
            return Json(id);
        }


        public async Task<IActionResult> DeleteAdvancePayment(Guid id)
        {
            await _prePaymentInfoAppService.DeleteAsync(id);
            return Json(id);
        }
        #endregion


        #region 退还预收款
        public async Task<IActionResult> RefundPayment(int? pageIdx, int size, PrePaymentInfoStatus? PrePaymentInfoStatus, string keyword = "")
        {
            var pa = pageIdx ?? 1;
            if (size == 0)
                size = 20;

            var s = await _prePaymentInfoAppService.GetPagedListAsync(pa, size, PrePaymentInfoType.退预交金, keyword, PrePaymentInfoStatus);
            if (Request.IsAjaxRequest())
                return PartialView("RefundPaymentPartial", s);

            return View(s);
        }

        /// <summary>
        /// 导出退还预收款列表
        /// </summary>
        /// <param name="keyword"></param>
        /// <returns></returns>
        public async Task<IActionResult> ExportRefundPayment(string keyword = "")
        {
            var list = await _prePaymentInfoAppService.GetAllListAsync(PrePaymentInfoType.退预交金, keyword);
            return DoExcel<PrePaymentInfoOutputDto>(list, _env);
        }

        public async Task<IActionResult> CreateRefundPayment()
        {
            var list = await _settlementAccountAppService.GetAllSettlementAccountAsync();
            ViewBag.Account = list.Select(o => new SelectListItem() { Value = o.Id.ToString(), Text = o.Name });
            return View(new PrePaymentInfoEnterDto() { PrePaymentInfoType = PrePaymentInfoType.退预交金 });
        }

        public async Task<IActionResult> EditRefundPayment(Guid id)
        {
            var entity = await _prePaymentInfoAppService.GetEnterDto(id);
            var list = await _settlementAccountAppService.GetAllSettlementAccountAsync();
            ViewBag.Account = list.Select(o => new SelectListItem() { Value = o.Id.ToString(), Text = o.Name });
            ViewBag.Id = id;
            return View(entity);
        }


        /// <summary>
        /// 获取预交余额
        /// </summary>
        /// <param name="id">餐厅Id</param>
        /// <returns></returns>
        public async Task<IActionResult> GetPaymentOver(Guid id)
        {
            var d = await _prePaymentInfoAppService.GetPaymentOverAsync(id);
            return Json(d);
        }
        #endregion

        #region 预收款余额
        public async Task<IActionResult> AdvanceOverage(int? pageIdx, int size, bool isnull = false, string keyword = "")
        {
            var pa = pageIdx ?? 1;
            if (size == 0)
                size = 20;

            var s = await _prePaymentInfoAppService.GetAdvanceOveragePagedListAsync(pa, size, isnull, keyword);
            if (Request.IsAjaxRequest())
                return PartialView("AdvanceOveragePartial", s);

            return View(s);
        }

        #endregion


        #region 分配收据
        public async Task<IActionResult> AssignReceipt(int? pageIdx, int size, long? DriverId, Guid? Line, DateTime? beginTime, DateTime? endTime, BalanceCycleEnum? BalanceCycleEnum, RestaurantPayStatus? RestaurantPayStatus, string AssignmentStatus = "", string keyword = "")
        {
            var pa = pageIdx ?? 1;

            if (size == 0)
                size = 20;

            var lines = await _distributionLineAppService.GetAllLineAsync();
            ViewBag.Line = lines.Select(o => new SelectListItem() { Value = o.Id.ToString(), Text = o.LineName });

            var users = await _userAppService.GetAllAgentPeoperAsync();
            ViewBag.Cashier = users.Select(o => new SelectListItem() { Value = o.Id.ToString(), Text = o.Name });

            if (Request.IsAjaxRequest())
            {
                var data = await _settlementInfoAppService.GetAssignReceiptListAsync(pa, size, DriverId, Line, beginTime, endTime, BalanceCycleEnum, RestaurantPayStatus, AssignmentStatus, keyword);
                return PartialView("AssignReceiptPartial", data);
            }


            return View();
        }

        public async Task<IActionResult> AssignUser()
        {
            var users = await _userAppService.GetAllAgentPeoperAsync();
            ViewBag.Cashier = users.Select(o => new SelectListItem() { Value = o.Id.ToString(), Text = o.Name });

            return View();

        }

        [HttpPost]
        public async Task<IActionResult> AssignUser(string Ids, long Cashier)
        {
            await _settlementInfoAppService.AssignReceiptAsync(Ids, Cashier);
            return Json("0");
        }
        /// <summary>
        /// 分配收据导出
        /// </summary>
        /// <returns></returns>
        public async Task<IActionResult> AssignReceiptExport(long? DriverId, Guid? Line, DateTime? beginTime, DateTime? endTime, BalanceCycleEnum? BalanceCycleEnum, RestaurantPayStatus? RestaurantPayStatus, string AssignmentStatus = "", string keyword = "")
        {
            var list = await _settlementInfoAppService.GetExportAssignReceiptListAsync(DriverId,Line,beginTime,endTime, BalanceCycleEnum,RestaurantPayStatus, AssignmentStatus,keyword);
            return DoExcel<SettlementExportDto>(list, _env);
        }

        #endregion

        #region 单据打印
        public async Task<IActionResult> SettlementPrint(string Ids)
        {
            var data = await _settlementInfoAppService.GetSettlementListAsync(Ids);
            var config = await _configInfoAppService.GetListAsync();
            ViewBag.Config = config;
            return View(data);
        }

        #endregion
    }
}
